iT邦幫忙

2022 iThome 鐵人賽

DAY 6
0
Modern Web

Hello TypeScript 菜鳥系列 第 6

Day 5. TypeScript內建的基本型別:any、unknown、void、never

  • 分享至 

  • xImage
  •  

今天來認識 anyunknownvoidnever,可能有些人會覺得很眼熟,曾在C++或是Java語言看過,但這些都是JavaScript沒有的型別,而是使用TypeScript才可以指定的型別。

any

any 型別可以說是其他型別的超集,可以代表任何已知變數值的變數型別。

因為未知型別的變數容易在編譯期出現錯誤,在不知道變數型別的狀況下,可以指定變數為 any 型別就能通過編譯檢查,以下舉例 any 型別的應用:

  1. 當轉換JavaScript專案為TypeScript專案時,可以用 any 型別當作過渡型別指定給不確定型別的變數;
  2. 引入第三方套件或資料時,可能不知道使用的套件變數、方法或資料的型別變數,這時就可以給予 any 型別:

any 型別看起來是蠻自由、蠻神通廣大的型別,由此可知JavaScript程式碼的變數在TypeScript的世界裡都是 any 型別。

此外,雖然現在也有很多第三方套件會在文件上說明型別,如下圖第三方動畫套件framer motion就在 animation props 旁明確寫出可接受 AnimationConotrolsTargetAndTransitionVariantLabelsboolean 型別的值

但在初學TypeScript使用第三方套件的時候,若官方文件沒有明確寫出型別,開發時很容易就會出現編譯錯誤,並在不確定如何解決編譯問題的情況下,無形中增加開發的時間成本,例如初學者可能一開始不知道可以去看GitHub原始程式碼使用的型別,或者不知道有的變數本身就可以接受 any 型別變數,如下圖也是Framer Motion提供的一個屬性:

這時可以先指定 any 型別暫時避免程式編譯時出現錯誤。

關於如何同時使用TypeScript和第三方套件的問題,可以參考一些網路文章,像是這篇:Way to use 3rd party libraries in TypeScript

unknown

unknown 還蠻有趣的,它的用法有點像是 any,任意變數可被賦予 any 型別變數的值;而 unknown 型別變數不能再賦值給其他型別的變數,舉例如下:

function(x: any, y: unknown){
    let n1: num = x;     // ok
    let s1: string = x;  // ok

    let n2: num = y;     // error
    let s2: num = y;     // error
}

unknonw 的作用在於,當你不確定一個變數的型別、又不想給予 any 型別,這時就可以給予 unknown 型別,來避免賦值給其他變數衍生出來的錯誤(可以想一下 any 型別的變數用法就和JavaScript的變數一樣就能理解了)

void

void 通常是用來代表 函式沒有回傳值 或是 函示回傳 undefined 的型別。
使用void的好處就是

  1. 明確表示函式沒有回傳值:寫程式可能有時會寫的落落長,結果看到最後才知道函式沒有 return 或是 return; (回傳 undefined),這時如果在函式開頭說明函式回傳的是 void 型別,就能在一開始立刻知道函式沒有回傳值。

    function returnNothing(): void {
         .....
    }
    
  2. void 可以避免特意用一個變數去接收函式回傳值:因為看到函式回傳void 型別,也就能知道不必特地建立一個變數來儲存函釋回傳值。

另外還需要注意的是,如果變數是void 型別

  • 只能賦值 undefined
  • 或者,如果tsconfig檔案有設定 strictNullCheck: false,就能賦值 null

never

最後是我覺得最難理解期應用的 never,因為這個型別是代表沒有值的意思,乍看和 void 有點像。

不過在TypeScript Tutorial是提到,never型別通常都是用來指稱會永遠拋出錯誤的函式,例如以下範例的兩種函式:

function sendError(msg: string): never {
    ...
    throw new Error(msg);

}

function rejectU(){
    return raiseError('rejected');
}

另外,如果是寫一個永遠都在迴圈中的函式,也就等於回傳 never:

function alwaysLoop(){
    while(true){
        ...
    }
    // implicitly return never
}

關於 never 的用途大都應該是用在拋出錯誤的時候,如果程式碼有結合拋出錯誤的函式,比較能快速抓出是哪段程式碼可能有錯,非常有助於除錯。


最後,如果需要更輕地知道哪種型別可接受或可賦予給哪些型別,可以參考TypeScript官方文件 Any, unknown, object, void, undefined, null, and never assignability 這段如下的表格,有關表格的詳細說明可參考官方文件:


參考資料
TypeScript Handbook
TypeScript Tutorial
TypeScript Tutorial: A step-by-step guide to learn TypeScript
Understanding Advanced Concepts in TypeScript


上一篇
Day 4. TypeScript 基本型別
下一篇
Day 6. TypeScript 參考型別:Array
系列文
Hello TypeScript 菜鳥31
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言